package ev.operator;

import ev.data.*;
import java.util.*;

public class InverOver {
	public Population inverover(Population old){
		//probability = 0.02
		double probability = 0.02;
		int len = old.getPopulationSize();
		int citynum  = old.getCities().size();
		Random r = new Random();
		for(int i = 0; i < len; i++){
			int cityid, cityInverid, cindex, cInverindex, tmp;
			int[] chromo = new int[citynum];
			for(int j = 0; j< citynum; j++){
				chromo[j] = old.getIndividual(i).getCityId(j);
			}
			cindex = r.nextInt(citynum);
			cityid = chromo[cindex];
			while(true){
				if(r.nextDouble() <= probability){
					cInverindex = r.nextInt(citynum);
					while(cInverindex == cindex){
						cInverindex = r.nextInt(citynum);
					}
					cityInverid = chromo[cInverindex];
				}
				else{
					tmp = r.nextInt(len);
					cInverindex = searchIndex(old.getIndividual(tmp).getList(), cityid);
					if(cInverindex == citynum-1){
						cInverindex = 0;
					}
					else{
						cInverindex++;
					}
					cityInverid = old.getIndividual(tmp).getCityId(cInverindex);
					cInverindex = searchIndex(chromo, cityInverid);
				}
				if(cInverindex == cindex-1 || cInverindex == cindex+1){
					//System.out.println("break"+cindex+" "+cInverindex);
					break;
				}
				//System.out.println(cindex+" "+cInverindex);
				chromo = inverse(chromo, cindex, cInverindex);
				cityid = cityInverid;
				cindex = searchIndex(chromo,cityid);
			}
			Individual s = new Individual(chromo);
			//print(s.getList());
			//System.out.println(s.getQuality());
			if(s.getQuality() < old.getIndividual(i).getQuality()){
				old.replace(s, i);
			}
		}
		return old;
	}
	public int searchIndex(int[] data, int target){
		for(int i = 0; i<data.length; i++){
			if(data[i] == target)
				return i;
		}
		return -1;
	} 
	public int[] inverse(int[] data, int ina, int inb){
		int in1 = ina<inb ? ina : inb;
		int in2 = ina<inb ? inb : ina;
		int[] tmp = new int[in2-in1];
		int i,j;
		for(i = in1+1, j = 0; i <= in2; i++,j++){
			tmp[j] = data[i];
		}
		for(i = in1+1, j = tmp.length-1; i <= in2; i++,j--){
			data[i] = tmp[j];
		}
		return data;
	}
	
	public void print(int[] data){
		for(int i =0; i< data.length;i++){
			System.out.print(data[i]+" ");
		}
		System.out.println();
	}
}
